package handler

import (
	"sort"

	"gitee.com/mangenotework/commander/common/entity"
	"gitee.com/mangenotework/commander/common/logger"
	"gitee.com/mangenotework/commander/common/protocol"
	"gitee.com/mangenotework/commander/common/utils"
	"gitee.com/mangenotework/commander/master/dao"

	"github.com/gin-gonic/gin"
)

// SlaveList
func SlaveList(c *gin.Context) {
	data, _ := new(dao.DaoSlave).GetALL()
	onlineMap := make(map[string]struct{})
	online := protocol.AllUdpClient.GetAllKey()
	for _, v := range online {
		onlineMap[v] = struct{}{}
	}
	for _, v := range data {
		_, ok := onlineMap[v.Slave]
		if ok {
			v.SlaveOnline = "在线"
		}else{
			v.SlaveOnline = "离线"
		}
		// 获取当前 cpu 和 内存使用情况
		v.NowCPURate = "0"
		v.NowMEMRate = "0"
		p, err := new(dao.DaoPerformance).GetNowPerformance(v.Slave)
		if err == nil {
			if p.CPU == nil {
				v.NowCPURate = "0"
			}else {
				v.NowCPURate = utils.StringValue(int(p.CPU.UseRate))
			}
			performanceMEM := 0
			if p.MEM != nil {
				performanceMEM = int(float64(p.MEM.MemUsed)/float64(p.MEM.MemTotal)*100)
			}
			v.NowMEMRate = utils.StringValue(performanceMEM)
		}
	}
	sort.Slice(data, func(i, j int) bool {
		return data[i].SlaveOnline < data[j].SlaveOnline
	})
	APIOutPut(c, 0, len(data), data, "")
}

// SlaveProcessList
func SlaveProcessList(c *gin.Context) {
	slave := c.Query("slave") // ip
	pg := c.Query("pg") // ip
	UDPSendOutHttp(c, slave, protocol.CMD_SlaveProcessList, []byte(pg))
}

// SlaveENVList
func SlaveENVList(c *gin.Context) {
	slave := c.Query("slave") // ip
	UDPSendOutHttp(c, slave, protocol.CMD_SlaveENVList, []byte(""))
}

// SlaveDiskInfo
func SlaveDiskInfo(c *gin.Context) {
	slave := c.Query("slave") // ip
	UDPSendOutHttp(c, slave, protocol.CMD_SlaveDiskInfo, []byte(""))
}

// SlavePathInfo
func SlavePathInfo(c *gin.Context) {
	slave := c.Query("slave") // ip
	path := c.Query("path") // ip
	UDPSendOutHttp(c, slave, protocol.CMD_SlavePathInfo, []byte(path))
}

// SlaveProcessKill
func SlaveProcessKill(c *gin.Context){
	slave := c.Query("slave") // ip
	pId := c.Query("pid")
	value := c.Query("value")
	if pId == "" {
		APIOutPut(c, 1, 0, "", "pid 不能爲空")
		return
	}
	arg := &entity.ProcessKillArg{
		PID : pId,
		Value : value,
	}
	buf, err := protocol.DataEncoder(arg)
	if err != nil {
		APIOutPut(c, 1, 0, "", err.Error())
		return
	}
	UDPSendOutHttp(c, slave, protocol.CMD_ProcessKill, buf)
}

// SlaveProcessInfo 查看进程信息
func SlaveProcessInfo(c *gin.Context) {
	slave := c.Query("slave") // ip
	pId := c.Query("pid")
	UDPSendOutHttp(c, slave, protocol.CMD_SlaveProcessInfo, []byte(pId))
}

// SlavePortInfo slave 端口使用情況
func SlavePortInfo(c *gin.Context) {
	slave := c.Query("slave") // ip
	UDPSendOutHttp(c, slave, protocol.CMD_SlavePortInfo, []byte(""))
}

// SlaveHosts 读取 hosts 文件
func SlaveHosts(c *gin.Context) {
	slave := c.Query("slave") // ip
	UDPSendOutHttp(c, slave, protocol.CMD_SlaveHosts, []byte(""))
}

// SlaveHostsUpdateParam
type SlaveHostsUpdateParam struct {
	Slave string `json:"slave"`
	HostsData string `json:"hosts_data"`
}

// SlaveHostsUpdate 更新 hosts文件
func SlaveHostsUpdate(c *gin.Context) {
	param := &SlaveHostsUpdateParam{}
	err := c.BindJSON(param)
	if err != nil {
		logger.Infof("json err = ", err)
		APIOutPut(c, 1, 0, "", err.Error())
		return
	}
	taskId := utils.IDMd5()
	arg := entity.SlaveHostsArg{
		TaskId: taskId,
		Data: param.HostsData,
	}
	buf, err := protocol.DataEncoder(arg)
	if err != nil {
		APIOutPut(c, 1, 0, "", err.Error())
		return
	}
	UDPSendOutHttp(c, param.Slave, protocol.CMD_SlaveHostsUpdate, buf)
}

// SlaveDir slave 目录与文件
func SlaveDir(c *gin.Context) {
	slave := c.Query("slave")
	path := c.Query("path")
	taskId := utils.IDMd5()
	arg := entity.GetSlavePathInfoArg{
		Path: path,
		TaskId: taskId,
	}
	buf, err := protocol.DataEncoder(arg)
	if err != nil {
		APIOutPut(c, 1, 0, "", err.Error())
		return
	}
	UDPSendOutHttp(c, slave, protocol.CMD_GetSlavePathInfo, buf)
}
